﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace EntityFramework.Helper.Model
{
    /// <summary>
    /// Helper class to use the EntityFramework Model.
    /// </summary>
    /// <typeparam name="T">Type of the model entity context.</typeparam>
    public class ModelHelper<T> where T : System.Data.Objects.ObjectContext
    {

        #region Fields

        /// <summary>
        /// Represent do ObjectContext.
        /// </summary>
        private static T s_context;

        #endregion

        #region Methods

        /// <summary>
        /// Initializes the current context.
        /// </summary>
        public static void Initialize()
        {
            // gets the context type.
            Type currentContextType = typeof(T);
            
            // gets the context ConstructorInfo.
            ConstructorInfo constructor = currentContextType.GetConstructor(new Type[0]);

            // instanciates the context.
            s_context = (T) constructor.Invoke(new object[0]);
        }

        /// <summary>
        /// Saves the changes done in the context.
        /// </summary>
        public static void SaveChanges()
        {
            try
            {
                s_context.SaveChanges();
            }
            catch
            {
                throw;
            }
        }

        /// <summary>
        /// Saves the changes done in the context.
        /// </summary>
        /// <param name="option">Defines the action on context save.</param>
        public void SaveChanges(System.Data.Objects.SaveOptions option)
        {
            try
            {
                s_context.SaveChanges(option);
            }
            catch
            {
                throw;
            }
        }

        /// <summary>
        /// Restarts the current context.
        /// </summary>
        public void Restart()
        {
            if (s_context != null)
            {
                // disposes the cotext.
                s_context.Dispose();
                s_context = null;

                // innitializa the context again.
                Initialize();
            }
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the current context.
        /// </summary>
        public static T Context
        {
            get
            {
                if (s_context == null)
                {
                    Initialize();
                }
                return s_context;
            }
        }

        #endregion
    }
}
